﻿using System;
using System.IO;
using System.Runtime.Serialization.Json;
using CoreLibrary.Collection;
using NLog;

namespace CoreLibrary.JsonNet {

    public class DataContractSerializer {

        private static readonly HashMap<Type, DataContractJsonSerializer>
           Serializers = new HashMap<Type, DataContractJsonSerializer>();

        public static bool TrySerialize (object obj, out string result) {
            try {
                result = Serialize(obj);
                return true;
            } catch (Exception) {
                result = null;
                return false;
            }
        }

        public static string Serialize (object obj) {
            try {
                var memoryStream = new MemoryStream();
                GetSerializer(obj.GetType()).WriteObject(memoryStream, obj);
                memoryStream.Position = 0;
                return IOUtil.ReadStringAndClose(memoryStream);
            } catch (Exception exception) {
                var errorMsg = string.Format("serialize json error[{0}]", exception.Message);
                LogManager.GetCurrentClassLogger().ErrorException(errorMsg, exception);
                throw;
            }
        }

        public static T Deserialize<T> (Stream stream) {
            var serializer = GetSerializer(typeof(T));
            var obj = serializer.ReadObject(stream);
            return (T)obj;
        }

        private static DataContractJsonSerializer GetSerializer (Type type) {
            lock (Serializers) {
                return Serializers.GetValueAddIfNotExist(type,
                       () => new DataContractJsonSerializer(type)
                );
            }
        }
    }
}